package com.tanglongan.designPattern.dp03_prototype.demo01;

import com.alibaba.fastjson.JSON;
import lombok.Getter;
import lombok.Setter;

public class JavaCloneableDemo01 {

    /**
     * super.clone（）方法直接从堆内存中以二进制流的方式进行复制，重新分配一个内存块，因此其效率很高。由于super.clone（）方法基于内存复制，因此不会调用对象的构造函数，也就是不需要经历初始化过程。
     */
    public static void main(String[] args) {
        testClone();            //19毫秒
        testNewConstructor();   //169毫秒
    }

    public static void testClone() {
        //创建原型对象
        ConcretePrototype type = new ConcretePrototype("original");
        System.out.println(type);
        //复制原型对象模式
        long start = System.currentTimeMillis();
        for (int i = 0; i < 500; i++) {
            ConcretePrototype clone = type.clone();
            clone.setDesc("clone_" + i);
            System.out.println(clone);
        }
        System.out.println("COST: " + (System.currentTimeMillis() - start));
    }

    public static void testNewConstructor() {
        //构造方法创建方式
        long start = System.currentTimeMillis();
        for (int i = 0; i < 500; i++) {
            ConcretePrototype prototype = new ConcretePrototype("original");
            System.out.println(prototype);
        }
        System.out.println("COST: " + (System.currentTimeMillis() - start));
    }


    @Getter
    @Setter
    static class ConcretePrototype implements Cloneable {
        private String desc;

        public ConcretePrototype(String desc) {
            this.desc = desc;
        }

        @Override
        protected ConcretePrototype clone() {
            try {
                return (ConcretePrototype) super.clone();
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        public String toString() {
            return JSON.toJSONString(this);
        }
    }
}
